// 用于放置公用方法
import nodemailer = require('nodemailer');

let transporter;
export default {
  // 创建发送邮件对象
  createTransporterInstance() {
    // 如果已经有发送者对象，则直接返回
    if (transporter) {
      return transporter;
    }
    // 1.创建发送者对象
    transporter = nodemailer.createTransport({
      host: 'smtp.qq.com',
      port: 465,
      secure: true, // true for 465, false for other ports
      auth: {
        user: '894817389@qq.com', // 发送邮件的邮箱
        pass: 'hluqtcvtrhflbfeg', // 邮箱对应的授权码
      },
    });
    return transporter;
  },
  // 2.创建需要发送的内容
  createEmailInfo(ctx, to:string) {
    // 使用 toString(16) 转成十六进制,截取随机生成的4个字符串
    const code = Math.random().toString(16).slice(2, 6)
      .toLocaleUpperCase();
      // 发送者对象
    const info = {
      from: '894817389@qq.com', // 谁发的
      to, // 发给谁
      subject: '小兔仙管理后台注册验证码', // 邮件标题
      text: `您正则注册小兔仙管理后台系统,您的验证码是:${code},验证码1分钟内有效!`, // 邮件内容
    };
      // 保存验证码到session中配合Redis
    ctx.session.email = {
      code,
      expire: Date.now() + 60 * 5000, // 验证码5分钟之后过期
    };
    return info;
  },
  // 3.发送邮件
  async sendEmailCode(ctx, to: string) {
    // 发送邮件对象
    const transporter = this.createTransporterInstance();
    // 发送的内容
    const info = this.createEmailInfo(ctx, to);
    // 异步发送
    return new Promise((resolve, reject) => {
      transporter.sendMail(info, (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data);
        }
      });
    });
  },
  // 校验验证码的方法
  verifyEmailCode(ctx, clientCode) { // 获取客户端传递过来的验证码 clientCode 参数的名称
    // 取出服务端中保存的验证码和过期时间
    const serverEmail = ctx.session.email;
    let serverCode;
    let serverExpire;
    try {
      serverCode = serverEmail.code; // 验证码信息
      serverExpire = serverEmail.expire; // 过期时间
    } catch (e) {
      throw new Error('请重新获取验证码');
    }
    // console.log(serverCode, serverExpire, clientCode);
    // 🔔注意点:邮箱验证码是可以多次输入的,频发发送邮件验证码是不友好的
    if (Date.now() > serverExpire) {
      throw new Error('验证码已过期');
    } else if (serverCode !== clientCode) {
      throw new Error('验证码不正确');
    }
    // 注意点: 邮箱验证码验证成功才清空
    ctx.session.email = null;
  },
};
